﻿using Bricks.Business.Models.Account;
using Bricks.Component.Utils;
using Bricks.Business.Data.Repositories.Account;
using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.Linq;
using System.Text;
using Bricks.Site.Models.Purview;
using Bricks.Business.Service.CommonSupport;

namespace Bricks.Business.Service.Impl
{
    [Export(typeof(IPurviewService))]
    public class PurviewService : IPurviewService
    {
        [Import]
        protected IOrgInfoRepository OrgRepository { get; set; }

        [Import]
        protected IMenuInfoRepository MenuInfoRepository { get; set; }

        [Import]
        protected IMenuActionRepository MenuActionRepository { get; set; }

        [Import]
        protected IOrgMenuActionRepository OrgMenuActionRepository { get; set; }

        [Import]
        protected IUserMenuActionRepository UserMenuActionRepository { get; set; }

        [Import]
        protected IRoleMenuActionRepository RoleMenuActionRepository { get; set; }

        [Import]
        protected IUserOrgRepository UserOrgRepository { get; set; }

        [Import]
        protected IUserInfoRepository UserInfoRepository { get; set; }

        public IQueryable<OrgInfo> Orgs
        {
            get { return OrgRepository.Entities; }
        }

        #region 方法

        #endregion

        /// <summary>
        /// 获取机构授权路径
        /// </summary>
        /// <param name="orgID">机构ID</param>
        /// <returns></returns>
        public List<PurviewPathView> GetOrgPurviewPath(Guid orgID)
        {
            /*此处目的是构造类似以下格式的记录
             * 系统设置-查看
             * 系统设置-功能管理-查看
             * 系统设置-功能管理-新增
             * 系统设置-功能管理-修改
             * 系统设置-功能管理-删除
             * 系统设置-菜单管理-查看
             * 系统设置-菜单管理-新增
             * 系统设置-菜单管理-修改
             * 
             * 需要的列可能有：
             * 菜单ID，菜单名称，菜单PID，功能名称
             */
            List<PurviewPathView> result = new List<PurviewPathView>();
            var list = from oma in OrgMenuActionRepository.Entities
                       join ma in MenuActionRepository.Entities on oma.MenuActionID equals ma.ID
                       join m in MenuInfoRepository.Entities on ma.MenuID equals m.ID
                       where oma.OrgID == orgID
                       orderby m.OrderNo, ma.OrderNo
                       select new MenuActionPath
                       {
                           MenuID = m.ID,
                           MenuName = m.MenuName,
                           MenuPID = m.PID,
                           ActionName = ma.ActionName,

                           InstanceID = oma.OrgID,
                           MenuActionID = ma.ID
                       };
            foreach (var item in list)
            {
                string actionName = item.ActionName;
                Guid? menuPID = item.MenuPID;
                string menuName = item.MenuName;
                Guid menuID = item.MenuID;

                //思路：从右往左加路径信息（查找PID情况）
                PurviewPathView newPath = new PurviewPathView();
                newPath.InstanceID = item.InstanceID;
                newPath.MenuActionID = item.MenuActionID;
                //newPath.PurviewPath = GetFullPath(list, item, string.Format("{0}-{1}", menuName, actionName));  //构造完整路径
                newPath.PurviewPath = GetPurviewPath(menuID, actionName);  //构造完整路径
                result.Add(newPath);
                //}

            }
            return result;
        }

        /// <summary>
        /// 获取权限的完整路径
        /// </summary>
        /// <param name="list"></param>
        /// <param name="item"></param>
        /// <returns></returns>
        //private string GetFullPath(IQueryable<MenuActionPath> list, MenuActionPath item, string path)
        //{
        //    //如果父节点不为空，则应向上查找
        //    if (item.MenuPID.HasValue)
        //    {
        //        var pMenu = list.FirstOrDefault(m => m.MenuID == item.MenuPID.Value);
        //        if (pMenu != null)
        //        {
        //            path = path.Insert(0, pMenu.MenuName + "-");
        //            path = GetFullPath(list, pMenu, path);
        //        }
        //    }
        //    //父节点为空则直接返回
        //    return path;
        //}

        /// <summary>
        /// 获取用户授权路径
        /// </summary>
        /// <param name="userOrgID"></param>
        /// <returns></returns>
        public List<PurviewPathView> GetUserPurviewPath(Guid userOrgID)
        {
            /*此处目的是构造类似以下格式的记录
             * 系统设置-查看
             * 系统设置-功能管理-查看
             * 系统设置-功能管理-新增
             * 系统设置-功能管理-修改
             * 系统设置-功能管理-删除
             * 系统设置-菜单管理-查看
             * 系统设置-菜单管理-新增
             * 系统设置-菜单管理-修改
             * 
             * 需要的列可能有：
             * 菜单ID，菜单名称，菜单PID，功能名称
             */

            List<PurviewPathView> result = new List<PurviewPathView>();

            var userOrg = UserOrgRepository.Entities.FirstOrDefault(m => m.ID == userOrgID);
            if (userOrg != null)
            {
                var org = OrgRepository.Entities.FirstOrDefault(m => m.ID == userOrg.OrgID);
                if (org != null)
                {
                    var list = from uma in UserMenuActionRepository.Entities
                               join ma in MenuActionRepository.Entities on uma.MenuActionID equals ma.ID
                               join m in MenuInfoRepository.Entities on ma.MenuID equals m.ID
                               where uma.UserID == userOrg.UserID && uma.OrgCode == org.OrgCode
                               orderby m.OrderNo, ma.OrderNo
                               select new MenuActionPath
                               {
                                   MenuID = m.ID,
                                   MenuName = m.MenuName,
                                   MenuPID = m.PID,
                                   ActionName = ma.ActionName,

                                   InstanceID = uma.UserID,
                                   MenuActionID = ma.ID
                               };
                    foreach (var item in list)
                    {
                        string actionName = item.ActionName;
                        Guid? menuPID = item.MenuPID;
                        string menuName = item.MenuName;
                        Guid menuID = item.MenuID;

                        //思路：从右往左加路径信息（查找PID情况）
                        PurviewPathView newPath = new PurviewPathView();
                        newPath.InstanceID = item.InstanceID;
                        newPath.MenuActionID = item.MenuActionID;
                        //newPath.PurviewPath = GetFullPath(list, item, string.Format("{0}-{1}", menuName, actionName));  //构造完整路径
                        newPath.PurviewPath = GetPurviewPath(menuID, actionName);  //构造完整路径
                        result.Add(newPath);
                        //}
                    }
                }
            }
            return result;
        }

        /// <summary>
        /// 获取权限组授权路径
        /// </summary>
        /// <param name="roleID">权限组ID</param>
        /// <returns></returns>
        public List<PurviewPathView> GetRolePurviewPath(Guid roleID)
        {
            /*此处目的是构造类似以下格式的记录
             * 系统设置-查看
             * 系统设置-功能管理-查看
             * 系统设置-功能管理-新增
             * 系统设置-功能管理-修改
             * 系统设置-功能管理-删除
             * 系统设置-菜单管理-查看
             * 系统设置-菜单管理-新增
             * 系统设置-菜单管理-修改
             * 
             * 需要的列可能有：
             * 菜单ID，菜单名称，菜单PID，功能名称
             */
            List<PurviewPathView> result = new List<PurviewPathView>();
            var list = from rma in RoleMenuActionRepository.Entities
                       join ma in MenuActionRepository.Entities on rma.MenuActionID equals ma.ID
                       join m in MenuInfoRepository.Entities on ma.MenuID equals m.ID
                       where rma.RoleID == roleID
                       orderby m.OrderNo, ma.OrderNo
                       select new MenuActionPath
                       {
                           MenuID = m.ID,
                           MenuName = m.MenuName,
                           MenuPID = m.PID,
                           ActionName = ma.ActionName,

                           InstanceID = rma.RoleID,
                           MenuActionID = ma.ID
                       };
            foreach (var item in list)
            {
                string actionName = item.ActionName;
                Guid? menuPID = item.MenuPID;
                string menuName = item.MenuName;
                Guid menuID = item.MenuID;

                //思路：从右往左加路径信息（查找PID情况）
                PurviewPathView newPath = new PurviewPathView();
                newPath.InstanceID = item.InstanceID;
                newPath.MenuActionID = item.MenuActionID;
                //newPath.PurviewPath = GetFullPath(list, item, string.Format("{0}-{1}", menuName, actionName));  //构造完整路径
                newPath.PurviewPath = GetPurviewPath(menuID, actionName);  //构造完整路径
                result.Add(newPath);
                //}

            }
            return result;
        }

        /// <summary>
        /// 获取菜单列表（只列出有权限的菜单）
        /// 超级管理员则列出所有
        /// 权限管理员则列出上级部门（只有上级，不往上继承）菜单
        /// 普通人应该不列出
        /// </summary>
        /// <returns></returns>
        public List<MenuInfo> GetPurviewMenuList()
        {
            List<MenuInfo> result = new List<MenuInfo>();
            var currentUser = SystemData.Instance.CurrentUser;
            //超级管理员则列出所有
            if (currentUser.UserType == UserType.SuperAdmin)
            {
                var list = from m in MenuInfoRepository.Entities
                           orderby m.OrderNo
                           select m;
                if (list != null && list.Count() > 0)
                {
                    result = list.ToList();
                }
            }
            //普通（可能包含部门权限管理员）
            else if (currentUser.UserType == UserType.Common)
            {
                //权限管理员则列出上级部门（只有上级，不往上继承）权限
                //找出当前用户作为权限管理员的部门集合
                var purviewOrgIDs = from uo in UserOrgRepository.Entities.Where(m => m.UserID == currentUser.ID && m.IsPurviewAdmin == true)
                                    select uo.OrgID;
                if (purviewOrgIDs != null && purviewOrgIDs.Count() > 0)
                {
                    //找出部门对应的权限集合
                    var purviewMenuActionIDs = from oma in OrgMenuActionRepository.Entities.Where(m => purviewOrgIDs.Contains(m.OrgID))
                                               select oma.MenuActionID;
                    //从所有权限中过滤上面找到的部门对应的权限集合
                    var list = from m in MenuInfoRepository.Entities
                               join ma in MenuActionRepository.Entities on m.ID equals ma.MenuID
                               where purviewMenuActionIDs.Contains(ma.ID) && ma.ActionCode == "View"
                               orderby m.OrderNo
                               select m;
                    if (list != null && list.Count() > 0)
                    {
                        result = list.ToList();
                    }
                }
            }
            return result;
        }

        /// <summary>
        /// 获取菜单对应的功能（勾选机构已有的菜单功能）
        /// Modify By Luozx 20140518：
        /// 超级管理员则列出所有
        /// 权限管理员则列出上级部门（只有上级，不往上继承）权限
        /// 普通人应该不列出
        /// </summary>
        /// <param name="menuID"></param>
        /// <returns></returns>
        public List<MenuActionView> GetMenuActionList()
        {
            List<MenuActionView> result = new List<MenuActionView>();
            var currentUser = SystemData.Instance.CurrentUser;
            //超级管理员则列出所有
            if (currentUser.UserType == UserType.SuperAdmin)
            {
                var list = from m in MenuActionRepository.Entities
                           orderby m.OrderNo
                           select new MenuActionView
                           {
                               ID = m.ID,
                               MenuID = m.MenuID,
                               ActionName = m.ActionName,
                               IsChecked = false
                           };
                if (list != null)
                {
                    result = list.ToList();
                }
            }
            //普通（可能包含部门权限管理员）
            else if (currentUser.UserType == UserType.Common)
            {
                //权限管理员则列出上级部门（只有上级，不往上继承）权限
                //找出当前用户作为权限管理员的部门集合
                var purviewOrgIDs = from uo in UserOrgRepository.Entities.Where(m => m.UserID == currentUser.ID && m.IsPurviewAdmin == true)
                                    select uo.OrgID;
                if (purviewOrgIDs != null && purviewOrgIDs.Count() > 0)
                {
                    //找出部门对应的权限集合
                    var purviewMenuActionIDs = from oma in OrgMenuActionRepository.Entities.Where(m => purviewOrgIDs.Contains(m.OrgID))
                                               select oma.MenuActionID;
                    //从所有权限中过滤上面找到的部门对应的权限集合
                    var list = from m in MenuActionRepository.Entities
                               where purviewMenuActionIDs.Contains(m.ID)
                               orderby m.OrderNo
                               select new MenuActionView
                               {
                                   ID = m.ID,
                                   MenuID = m.MenuID,
                                   ActionName = m.ActionName,
                                   IsChecked = false
                               };
                    if (list != null)
                    {
                        result = list.ToList();
                    }
                }
            }
            return result;
        }

        /// <summary>
        /// 获取权限路径（根据菜单ID和功能名称构造）
        /// </summary>
        /// <param name="menuID">菜单ID</param>
        /// <param name="actionName">功能名称</param>
        /// <param name="path">已有路径（递归构造）</param>
        /// <returns></returns>
        public string GetPurviewPath(Guid menuID, string actionName, string path = null)
        {
            //string result = string.Empty;
            var menu = MenuInfoRepository.Entities.FirstOrDefault(m => m.ID == menuID);
            if (menu != null)
            {
                if (String.IsNullOrEmpty(path))
                {
                    path = string.Format("{0}-{1}", menu.MenuName, actionName);
                }
                else
                {
                    path = string.Format("{0}-{1}", menu.MenuName, path);
                }
                //如果还有上级节点，则继续递归
                if (menu.PID.HasValue && !menu.PID.Value.Equals(Guid.Empty))
                {
                    path = GetPurviewPath(menu.PID.Value, actionName, path);
                }
            }
            return path;
        }

        /// <summary>
        /// 保存机构权限
        /// </summary>
        /// <param name="dict"></param>
        /// <returns></returns>
        public OperationResult SaveOrgPurviewDict(Dictionary<Guid, List<PurviewPathView>> dict)
        {
            //思路：清空原有记录，加入已配置的记录
            OperationResult result = new OperationResult(OperationResultType.NoChanged, "NoChanged");
            try
            {
                //找出数据库中原有的记录
                var existOrgPurview = OrgMenuActionRepository.Entities.Where(m => dict.Keys.Contains(m.OrgID)).ToList();  //如果此处不ToList()，则将提示事务已经在另一线程启动
                if (existOrgPurview != null)
                {
                    //清空原有记录
                    foreach (var item in existOrgPurview)
                    {
                        OrgMenuActionRepository.Delete(item);
                    }
                    //清空后重新加入已配置的记录
                    //循环dict，每个dict代表一个机构
                    foreach (var item in dict)
                    {
                        //循环value，每个value都是一个权限列表，重新加入到数据库中
                        foreach (var op in item.Value)
                        {
                            OrgMenuAction newOMA = new OrgMenuAction();
                            newOMA.ID = GuidHelper.NewGuid();
                            newOMA.OrgID = op.InstanceID;
                            newOMA.MenuActionID = op.MenuActionID;
                            newOMA.IsDeleted = false;
                            newOMA.AddDate = DateTime.Now;
                            OrgMenuActionRepository.Insert(newOMA);
                        }
                    }
                }
                result = new OperationResult(OperationResultType.Success, "机构授权成功");
            }
            catch (Exception ex)
            {
                result = new OperationResult(OperationResultType.Error, ex.Message);
                return result;
            }
            return result;
        }

        /// <summary>
        /// 保存用户权限
        /// </summary>
        /// <param name="dict"></param>
        /// <returns></returns>
        public OperationResult SaveUserPurviewDict(Dictionary<Guid, List<PurviewPathView>> dict)
        {
            //思路：清空原有记录，加入已配置的记录
            OperationResult result = new OperationResult(OperationResultType.NoChanged, "NoChanged");
            try
            {
                //此处的Key存的是UserOrgID，需要从中取出UserID集合
                List<Guid> userIDList = new List<Guid>();
                //需同时取出OrgID，方便
                List<string> orgCodeList = new List<string>();
                var userOrgList = UserOrgRepository.Entities.Where(m => dict.Keys.Contains(m.ID)).ToList();
                foreach (var item in userOrgList)
                {
                    userIDList.Add(item.UserID);
                    orgCodeList.Add(GetOrgCoeByOrgID(item.OrgID));
                }

                //找出数据库中原有的记录
                var existUserPurview = UserMenuActionRepository.Entities.Where(m => userIDList.Contains(m.UserID) && orgCodeList.Contains(m.OrgCode)).ToList();  //如果此处不ToList()，则将提示事务已经在另一线程启动
                if (existUserPurview != null)
                {
                    //清空原有记录
                    foreach (var item in existUserPurview)
                    {
                        UserMenuActionRepository.Delete(item);
                    }
                    //清空后重新加入已配置的记录
                    //循环dict，每个dict代表一个UserOrg
                    foreach (var item in dict)
                    {
                        //循环value，每个value都是一个权限列表，重新加入到数据库中
                        foreach (var op in item.Value)
                        {
                            UserMenuAction newUMA = new UserMenuAction();
                            newUMA.ID = GuidHelper.NewGuid();
                            //newUMA.UserID = op.InstanceID;
                            newUMA.UserID = op.InstanceID;
                            newUMA.MenuActionID = op.MenuActionID;
                            newUMA.IsDeleted = false;
                            newUMA.AddDate = DateTime.Now;
                            newUMA.OrgCode = GetOrgCodeByUserOrgID(item.Key);  //根据UserOrgID取得OrgCode（此处可能较严重影响性能）
                            UserMenuActionRepository.Insert(newUMA);
                        }
                    }
                }
                result = new OperationResult(OperationResultType.Success, "用户授权成功");
            }
            catch (Exception ex)
            {
                result = new OperationResult(OperationResultType.Error, ex.Message);
                return result;
            }
            return result;
        }

        /// <summary>
        /// 保存权限组权限
        /// </summary>
        /// <param name="dict"></param>
        /// <returns></returns>
        public OperationResult SaveRolePurviewDict(Dictionary<Guid, List<PurviewPathView>> dict)
        {
            //思路：清空原有记录，加入已配置的记录
            OperationResult result = new OperationResult(OperationResultType.NoChanged, "NoChanged");
            try
            {
                //找出数据库中原有的记录
                var existRolePurview = RoleMenuActionRepository.Entities.Where(m => dict.Keys.Contains(m.RoleID)).ToList();  //如果此处不ToList()，则将提示事务已经在另一线程启动
                if (existRolePurview != null)
                {
                    //清空原有记录
                    foreach (var item in existRolePurview)
                    {
                        RoleMenuActionRepository.Delete(item);
                    }
                    //清空后重新加入已配置的记录
                    //循环dict，每个dict代表一个机构
                    foreach (var item in dict)
                    {
                        //循环value，每个value都是一个权限列表，重新加入到数据库中
                        foreach (var op in item.Value)
                        {
                            RoleMenuAction newRMA = new RoleMenuAction();
                            newRMA.ID = GuidHelper.NewGuid();
                            newRMA.RoleID = op.InstanceID;
                            newRMA.MenuActionID = op.MenuActionID;
                            newRMA.IsDeleted = false;
                            newRMA.AddDate = DateTime.Now;
                            RoleMenuActionRepository.Insert(newRMA);
                        }
                    }
                }
                result = new OperationResult(OperationResultType.Success, "权限组授权成功");
            }
            catch (Exception ex)
            {
                result = new OperationResult(OperationResultType.Error, ex.Message);
                return result;
            }
            return result;
        }

        /// <summary>
        /// 根据OrgID获取OrgCode
        /// </summary>
        /// <param name="orgID"></param>
        /// <returns></returns>
        private string GetOrgCoeByOrgID(Guid orgID)
        {
            string result = string.Empty;
            var org = OrgRepository.Entities.FirstOrDefault(m => m.ID == orgID);  //找出Org记录
            if (org != null)
            {
                result = org.OrgCode;
            }
            return result;
        }

        /// <summary>
        /// 根据UserOrgID取得UserID
        /// </summary>
        /// <param name="userOrgID"></param>
        /// <returns></returns>
        public Guid GetUserIDByUserOrgID(Guid userOrgID)
        {
            Guid result = Guid.Empty;
            var userOrg = UserOrgRepository.Entities.FirstOrDefault(m => m.ID == userOrgID);  //找出UserOrg记录
            if (userOrg != null)
            {
                var user = UserInfoRepository.Entities.FirstOrDefault(m => m.ID == userOrg.UserID);  //找出Org记录
                if (user != null)
                {
                    result = user.ID;  //赋予Code
                }
            }
            return result;
        }

        /// <summary>
        /// 根据UserOrgID取得OrgCode
        /// </summary>
        /// <param name="userOrgID"></param>
        /// <returns></returns>
        private string GetOrgCodeByUserOrgID(Guid userOrgID)
        {
            string result = string.Empty;
            var userOrg = UserOrgRepository.Entities.FirstOrDefault(m => m.ID == userOrgID);  //找出UserOrg记录
            if (userOrg != null)
            {
                var org = OrgRepository.Entities.FirstOrDefault(m => m.ID == userOrg.OrgID);  //找出Org记录
                if (org != null)
                {
                    result = org.OrgCode;  //赋予Code
                }
            }
            return result;
        }

        /// <summary>
        /// 菜单功能类（为实现权限路径显示的临时类）
        /// </summary>
        public class MenuActionPath
        {
            public Guid MenuID { get; set; }

            public string MenuName { get; set; }

            public Guid? MenuPID { get; set; }

            public string ActionName { get; set; }

            //为实现临时保存，添加以下属性
            public Guid InstanceID { get; set; }

            public Guid MenuActionID { get; set; }
        }
    }
}
